/* ram1(+tasma_wejsciowa,+program,-pamiec,-tasma_wyjsciowa)
ram1([4,5],[[read,1],[read,2],[petla,load,1],[mult,[=,4]],[store,1],[load,2],[sub,[=,1]],[store,2],[jgtz,petla],[write,2],[halt]],M,L).
*/
 
/*PRACA CIĄGŁA*/
 
ram1(L1,L2,O1,Ot):-
        nth0(C,L2,E),
        ram(L1,L2,E,_,_,_,C,O1,Ot),
        !.

ram(L1,L2,[_,E,X],A,M,L3,C,O1,Ot):-
		ram(L1,L2,[E,X],A,M,L3,C,O1,Ot).
        
ram([H|T],L2,[read,0],_,M,L3,C,O1,Ot):-
        C2 is C+1,
        nth0(C2,L2,E),
        ram(T,L2,E,H,M,L3,C2,O1,Ot). 	
ram([H|T],L2,[read,X],A,[],L3,C,O1,Ot):-
        C2 is C+1,
        nth0(C2,L2,E),
        ram(T,L2,E,A,[[X,H]],L3,C2,O1,Ot).      
ram([H|T],L2,[read,X],A,M,L3,C,O1,Ot):-
        C2 is C+1,
        nth0(C2,L2,E),
        delete(M,[X,_],M2),
        ram(T,L2,E,A,[[X,H]|M2],L3,C2,O1,Ot).
   
ram(L,L2,[write,0],A,M,[],C,O1,Ot):-
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A,M,A,C2,O1,Ot). 
ram(L,L2,[write,0],A,M,L1,C,O1,Ot):-
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A,M,[A|L1],C2,O1,Ot). 
ram(L,L2,[write,X],A,M,[],C,O1,Ot):-
        szukaj(X,M,E),
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A,M,E,C2,O1,Ot).    
ram(L,L2,[write,X],A,M,L1,C,O1,Ot):-
        szukaj(X,M,E),
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A,M,[E|L1],C2,O1,Ot).  
ram(L,L2,[write,[=,X]],A,M,[],C,O1,Ot):-
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A,M,X,C2,O1,Ot).    
ram(L,L2,[write,[=,X]],A,M,L1,C,O1,Ot):-
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A,M,[X|L1],C2,O1,Ot). 		
        
ram(L,L2,[load,[=,X]],_,M,L1,C,O1,Ot):-
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,X,M,L1,C2,O1,Ot).
ram(L,L2,[load,X],_,M,L1,C,O1,Ot):-
        szukaj(X,M,E),
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,E,M,L1,C2,O1,Ot).

ram(L,L2,[store,X],A,M,L1,C,O1,Ot):-
        C2 is C+1,
        nth0(C2,L2,E),
		delete(M,[X,_],M2),
        ram(L,L2,E,A,[[X,A]|M2],L1,C2,O1,Ot).

ram(L,L2,[add,[^,0]],A,M,L1,C,O1,Ot):-
        szukaj(A,M,E),
        szukaj(E,M,E3),
        A1 is A+E3,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).		
ram(L,L2,[add,[-,0]],A,M,L1,C,O1,Ot):-
        A1 is A+A,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).		
ram(L,L2,[add,[=,X]],A,M,L1,C,O1,Ot):-
        A1 is A+X,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
ram(L,L2,[add,[^,X]],A,M,L1,C,O1,Ot):-
        szukaj(X,M,E),
        szukaj(E,M,E3),
        A1 is A+E3,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
ram(L,L2,[add,[-,X]],A,M,L1,C,O1,Ot):-
        szukaj(X,M,E),
        A1 is A+E,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
        
ram(L,L2,[sub,[^,0]],A,M,L1,C,O1,Ot):-
        szukaj(A,M,E),
        szukaj(E,M,E3),
        A1 is A-E3,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
ram(L,L2,[sub,[-,0]],A,M,L1,C,O1,Ot):-
        A1 is A-A,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot). 
ram(L,L2,[sub,[=,X]],A,M,L1,C,O1,Ot):-
		A1 is A-X,
        C2 is C+1,
        nth0(C2,L2,E2),
		
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
ram(L,L2,[sub,[^,X]],A,M,L1,C,O1,Ot):-
        szukaj(X,M,E),
        szukaj(E,M,E3),
        A1 is A-E3,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
ram(L,L2,[sub,[-,X]],A,M,L1,C,O1,Ot):-
        szukaj(X,M,E),
        A1 is A-E,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).

ram(L,L2,[mult,[^,0]],A,M,L1,C,O1,Ot):-
        szukaj(A,M,E),
        szukaj(E,M,E3),
        A1 is A*E3,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
ram(L,L2,[mult,[-,0]],A,M,L1,C,O1,Ot):-
        A1 is A*A,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot). 		
ram(L,L2,[mult,[=,X]],A,M,L1,C,O1,Ot):-
        A1 is A*X,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
ram(L,L2,[mult,[^,X]],A,M,L1,C,O1,Ot):-
        szukaj(X,M,E),
        szukaj(E,M,E3),
        A1 is A*E3,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).  
ram(L,L2,[mult,[-,X]],A,M,L1,C,O1,Ot):-
        szukaj(X,M,E),
        A1 is A*E,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
        
ram(L,L2,[div,[^,0]],A,M,L1,C,O1,Ot):-
        szukaj(A,M,E),
        szukaj(E,M,E3),
        A1 is A//E3,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot). 
ram(L,L2,[div,[-,0]],A,M,L1,C,O1,Ot):-
        A1 is A//A,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
ram(L,L2,[div,[=,X]],A,M,L1,C,O1,Ot):-
        A1 is A//X,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
ram(L,L2,[div,[^,X]],A,M,L1,C,O1,Ot):-
        szukaj(X,M,E),
        szukaj(E,M,E3),
        A1 is A//E3,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
ram(L,L2,[div,[-,X]],A,M,L1,C,O1,Ot):-
        szukaj(X,M,E),
        A1 is A//E,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A1,M,L1,C2,O1,Ot).
        
ram(L,L2,[jgtz,X],A,M,L1,_,O1,Ot):-
        A > 0,
        szukaj2(X,L2,E2),
		nth0(C2,L2,[X|E2]),
        ram(L,L2,E2,A,M,L1,C2,O1,Ot).
ram(L,L2,[jgtz,_],A,M,L1,C,O1,Ot):-
        A =< 0,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A,M,L1,C2,O1,Ot).
        
ram(L,L2,[jmpz,X],A,M,L1,_,O1,Ot):-
        A =< 0,
        szukaj2(X,L2,E2),
		nth0(C2,L2,[X|E2]),
        ram(L,L2,E2,A,M,L1,C2,O1,Ot).
ram(L,L2,[jmpz,_],A,M,L1,C,O1,Ot):-
        A > 0,
        C2 is C+1,
        nth0(C2,L2,E2),
        ram(L,L2,E2,A,M,L1,C2,O1,Ot).
        
ram(L,L2,[jump,X],A,M,L1,_,O1,Ot):-
        szukaj2(X,L2,E2),
		nth0(C2,L2,[X|E2]),
        ram(L,L2,E2,A,M,L1,C2,O1,Ot).

ram(_,_,[halt],A,[],L,_,[[0,A]],L):-
        !.	
ram(_,_,[_,halt],A,[],L,_,[[0,A]],L):-
        !.   
ram(_,_,[halt],A,M,L,_,[[0,A]|M],L):-
        !.	
ram(_,_,[_,halt],A,M,L,_,[[0,A]|M],L):-
        !.

/*PRACA KROKOWA*/		

		
ram_s(L1,L2,A_IN,M_IN,L_WYJSCIOWA_IN,C_IN,L_OUT,A_OUT,M_OUT,L_WYJSCIOWA_OUT,C_OUT):-
	nth0(C_IN,L2,E),
	ram2(L1,L2,E,A_IN,M_IN,L_WYJSCIOWA_IN,C_IN,L_OUT,A_OUT,M_OUT,L_WYJSCIOWA_OUT,C_OUT).
	
ram2(L1,L2,[_,E,X],A,M,L3,C, L1_O,A_O,M_O,L3_O,C_O):-
	ram2(L1,L2,[E,X],A,M,L3,C, L1_O,A_O,M_O,L3_O,C_O).
						
ram2([H|T],_,[read,0],_,M,L3,C, T,H,M3,L3,C2):-
		delete(M,[0,_],M2),
		append(M2,[[0,H]],M3),
        C2 is C+1,
		!.          
ram2([H|T],_,[read,X],A,[],L3,C, T,A,[[X,H]],L3,C2):-
        C2 is C+1,
		!.
ram2([H|T],_,[read,X],A,M,L3,C, T,A,M3,L3,C2):-
        delete(M,[X,_],M2),
		append(M2,[[X,H]],M3),
		C2 is C+1.
               
ram2(L,_,[write,0],A,M,[],C, L,A,M,A,C2):-
        C2 is C+1,
		!.      
ram2(L,_,[write,0],A,M,L1,C, L,A,M,[A|L1],C2):-
        C2 is C+1,
		!.     
ram2(L,_,[write,X],A,M,[],C, L,A,M,E,C2):-
        szukaj(X,M,E),
        C2 is C+1,
		!.		
ram2(L,_,[write,X],A,M,L1,C, L,A,M,[E|L1],C2):-
        szukaj(X,M,E),
        C2 is C+1.      
ram2(L,_,[write,[=,X]],A,M,[],C, L,A,M,X,C2):-
        C2 is C+1.      
ram2(L,_,[write,[=,X]],A,M,L1,C, L,A,M,[X|L1],C2):-
        C2 is C+1.
           
ram2(L,_,[load,[=,X]],_,M,L1,C, L,X,M,L1,C2):-
        C2 is C+1.     
ram2(L,_,[load,X],_,M,L1,C, L,E,M,L1,C2):-
        szukaj(X,M,E),
        C2 is C+1.
        
ram2(L,_,[store,X],A,[],L1,C, L,A,[[X,A]],L1,C2):-
        C2 is C+1,
		!.
ram2(L,_,[store,X],A,M,L1,C, L,A,[[X,A]|M2],L1,C2):-
        C2 is C+1,
		delete(M,[X,_],M2).
       
ram2(L,_,[add,[^,0]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(A,M,E),
        szukaj(E,M,E3),
        A1 is A+E3,
        C2 is C+1,
		!.
ram2(L,_,[add,[-,0]],A,M,L1,C, L,A1,M,L1,C2):-
        A1 is A+A,
        C2 is C+1,
		!.
ram2(L,_,[add,[=,X]],A,M,L1,C, L,A1,M,L1,C2):-
        A1 is A+X,
        C2 is C+1.        
ram2(L,_,[add,[^,X]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(X,M,E),
        szukaj(E,M,E3),
        A1 is A+E3,
        C2 is C+1.        
ram2(L,_,[add,[-,X]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(X,M,E),
        A1 is A+E,
        C2 is C+1.
                
ram2(L,_,[sub,[^,0]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(A,M,E),
        szukaj(E,M,E3),
        A1 is A-E3,
        C2 is C+1,
		!.              
ram2(L,_,[sub,[-,0]],A,M,L1,C, L,A1,M,L1,C2):-
        A1 is A-A,
        C2 is C+1,
		!.            
ram2(L,_,[sub,[=,X]],A,M,L1,C, L,A1,M,L1,C2):-
		A1 is A-X,
        C2 is C+1.          
ram2(L,_,[sub,[^,X]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(X,M,E),
        szukaj(E,M,E3),
        A1 is A-E3,
        C2 is C+1.           
ram2(L,_,[sub,[-,X]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(X,M,E),
        A1 is A-E,
        C2 is C+1.
        
ram2(L,_,[mult,[^,0]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(A,M,E),
        szukaj(E,M,E3),
        A1 is A*E3,
        C2 is C+1,
		!.             
ram2(L,_,[mult,[-,0]],A,M,L1,C, L,A1,M,L1,C2):-
        A1 is A*A,
        C2 is C+1,
		!.      
ram2(L,_,[mult,[=,X]],A,M,L1,C, L,A1,M,L1,C2):-
        A1 is A*X,
        C2 is C+1.             
ram2(L,_,[mult,[^,X]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(X,M,E),
        szukaj(E,M,E3),
        A1 is A*E3,
        C2 is C+1.              
ram2(L,_,[mult,[-,X]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(X,M,E),
        A1 is A*E,
        C2 is C+1.
               
ram2(L,_,[div,[^,0]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(A,M,E),
        szukaj(E,M,E3),
        A1 is A//E3,
        C2 is C+1,
		!.               
ram2(L,_,[div,[-,0]],A,M,L1,C, L,A1,M,L1,C2):-
        A1 is A//A,
        C2 is C+1,
		!.           
ram2(L,_,[div,[=,X]],A,M,L1,C, L,A1,M,L1,C2):-
        A1 is A//X,
        C2 is C+1.           
ram2(L,_,[div,[^,X]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(X,M,E),
        szukaj(E,M,E3),
        A1 is A//E3,
        C2 is C+1.
              
ram2(L,_,[div,[-,X]],A,M,L1,C, L,A1,M,L1,C2):-
        szukaj(X,M,E),
        A1 is A//E,
        C2 is C+1.    
        
ram2(L,L2,[jgtz,X],A,M,L1,_, L,A,M,L1,C2):-
        A > 0,
        szukaj2(X,L2,E2),
		nth0(C2,L2,[X|E2]).
ram2(L,_,[jgtz,_],A,M,L1,C, L,A,M,L1,C2):-
        A =< 0,
        C2 is C+1.
           
ram2(L,L2,[jmpz,X],A,M,L1,_, L,A,M,L1,C2):-
        A =< 0,
        szukaj2(X,L2,E2),
		nth0(C2,L2,[X|E2]).     
ram2(L,_,[jmpz,_],A,M,L1,C, L,A,M,L1,C2):-
        A > 0,
        C2 is C+1.
           
ram2(L,L2,[jump,X],A,M,L1,_, L,A,M,L1,C2):-
        szukaj2(X,L2,E2),
		nth0(C2,L2,[X|E2]).
        
ram2(L,_,[halt],A,[],L1,C, L,A,[[0,A]],L1,C):-
        !.	
ram2(L,_,[_,halt],A,[],L1,C, L,A,[[0,A]],L1,C):-
        !.	      
ram2(L,_,[halt],A,M,L1,C, L,A,[[0,A]|M],L1,C):-
        !.	
ram2(L,_,[_,halt],A,M,L1,C, L,A,[[0,A]|M],L1,C):-
        !.	
       
/* FUNKCJE POMOCNICZE*/
      
szukaj(X,[[X1,E]|_],E):-
        X1 = X,!.
szukaj(X,[[X1,_]|T],E):-
        X1 \=  X,
        szukaj(X,T,E).
szukaj(_,[],_).

szukaj2(X,[[X1|E]|_],E):-
        X1 = X,
		!.
szukaj2(X,[[X1|_]|T],E):-
        X1 \=  X,
        szukaj2(X,T,E).